package
{
	import com.freshcity.core.GlobalVar;
	import com.freshcity.core.OpCodes;
	import com.freshcity.lib.event.DataEvent;
	import com.freshcity.utils.StringUtil;
	
	import flash.display.GradientType;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.external.ExternalInterface;
	import flash.net.Socket;
	import flash.net.URLRequest;
	import flash.system.Security;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;

	[SWF(width="790", height="570", frameRate="30", wmode="direct")]
	public class ServerLite extends Sprite
	{
		private var sc:Socket;
		private var callback:Function;

		private var byteBuffer:ByteArray=new ByteArray(); //数据缓存
		private var dataLength:int; //接收到的数据长度
		private var headLen:int=4; //数据包首部长度
		private var readFlag:Boolean;
		private var userData:*;

		//private var mainPath:String="";
		private var loader:Loader;
		private var loadTxt:TextField;
		private var loadBar:Shape;
		private var barBack:Shape;

		public function ServerLite()
		{
			Security.allowDomain("*");
			Security.allowInsecureDomain("*");
			Security.loadPolicyFile('xmlsocket://' + GlobalVar.SOCKET_IP + ':' + GlobalVar.SOCKET_PORT);

			this.addEventListener(Event.ADDED_TO_STAGE, this.initApp);
		}

		private function initApp(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, this.initApp);

			//Security.loadPolicyFile("xmlsocket://www.thenicecity.com/crossdomain.xml");
			sc=new Socket();
			sc.addEventListener(ProgressEvent.SOCKET_DATA, receivedHandler);
			sc.addEventListener(Event.CONNECT, onConnect);
			sc.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
			sc.connect(GlobalVar.SOCKET_IP, GlobalVar.SOCKET_PORT);
			
			var stageW:Number = stage.stageWidth;
			var stageH:Number = stage.stageHeight;
			
			//创建文本
			loadTxt=new TextField();
			loadTxt.autoSize=TextFieldAutoSize.CENTER;
			var format:TextFormat = new TextFormat("黑体",13);
			loadTxt.defaultTextFormat = format;
			loadTxt.text="准备加载...";
			loadTxt.textColor=0x000000;
			loadTxt.selectable=false;
			loadTxt.x=stageW/2-loadTxt.width/2;
			loadTxt.y=stageH/2-loadTxt.height/2;
			//设置本文件放置于舞台中央
			addChild(loadTxt);
			
			//绘制进度条底色
			barBack=new Shape();
			barBack.graphics.lineStyle(1,0x000000,1);
			barBack.graphics.beginFill(0xcccccc,.5);
			barBack.graphics.drawRect(0,0,200,8);
			barBack.graphics.endFill();
			barBack.x=stageW/2-barBack.width/2;
			barBack.y=loadTxt.y+loadTxt.height+5;
			addChild(barBack)
			
			loadBar=new Shape();
			loadBar.graphics.lineStyle(1,0x000000,.5);
			//采用渐变填充 红--黄
			//loadBar.graphics.beginGradientFill(GradientType.LINEAR,[0xff0000,0xffff00],[100,100],[0,255]);
			loadBar.graphics.beginFill(0x009900);
			loadBar.graphics.drawRect(0,0,200,8);
			loadBar.graphics.endFill();
			loadBar.x=stageW/2-loadBar.width/2;
			loadBar.y=loadTxt.y+loadTxt.height+5;
			addChild(loadBar);			
			loadBar.scaleX=0.01;
		}

		private function onIOError(event:Event):void
		{
			//connectCallBack(event)
			//FAlert.instance.show('抱歉，数据服务中断，请稍后访问！',FAlert.ALERT);
			//new FWindow(PBE.mainClass);
		}

		public function onConnect(event:Event):void
		{
			ExternalInterface.addCallback('loginFunc', onLogin);
			ExternalInterface.addCallback('registerFunc', onRegister);
			ExternalInterface.addCallback('loginOthersFunc', onOthersLogin);
			ExternalInterface.call("showConnectSuc");
		}

		public function onOthersLogin(paras:*):void
		{
			GlobalVar.version = paras.version;
			GlobalVar.LOGOBAR_IMAGE_ID = paras.logoBarId;
			var src:String = paras.src;
			var code:String = paras.code;
			var uid:String = paras.uid;
			var recomId:String = paras.recomId;
			var isApp:String = paras.isApp;
			
			if (src == '360')
			{
				send(OpCodes.LOGIN_360, {src: src, code: code, uid: uid, recom: recomId, isapp: isApp}, onLoginHandler);
			}
			if (src == 'renren')
			{
				send(OpCodes.LOGIN_RENREN, {src: src, code: code, uid: uid, recom: recomId, isapp: isApp}, onLoginHandler);
			}
			if (src == 'sina')
			{
				send(OpCodes.LOGIN_SINA, {src: src, code: code, uid: uid, recom: recomId, isapp: isApp}, onLoginHandler);
			}
			if (src == 'qq')
			{
				send(OpCodes.LOGIN_QQ, {src: src, code: code, uid: uid, pf: paras.pf, isapp: isApp}, onLoginHandler);
			}
		}

		public function onRegister(paras:*):void
		{
			GlobalVar.version = paras.version;
			GlobalVar.LOGOBAR_IMAGE_ID = paras.logoBarId;
			var id:String = paras.id;
			var pass:String = paras.pass;
			var recomId:String = paras.recomId;
			send(OpCodes.REGISTER, {id: id, password: pass, src: "local", recom: recomId}, onRegisterHandler);
		}

		private function onRegisterHandler(data:*):void
		{
			if (data is String)
			{
				ExternalInterface.call("registerFail", String(data));
			}
			else
			{
				mainLoad(data);
			}
		}

		public function onLogin(paras:*):void
		{
			GlobalVar.version = paras.version;
			GlobalVar.LOGOBAR_IMAGE_ID = paras.logoBarId;
			var id:String = paras.id;
			var pass:String = paras.pass;
			send(OpCodes.LOGIN, {id: id, pass: pass}, onLoginHandler);
		}

		private function onLoginHandler(data:*):void
		{
			if (data is String)
			{
				ExternalInterface.call("loginFail", String(data));
			}
			else
			{
				ExternalInterface.call("loadMainPage");
				mainLoad(data);
			}
		}

		private function mainLoad(data:*):void
		{
			this.userData=data;
			loader=new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.loadCompleteHandler);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, this.loadProgressHandler);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.loadErrorHandler);
			loader.load(new URLRequest(GlobalVar.MAIN_PATH + "/LoadBar.swf?v=" + GlobalVar.version));
		}

		private function loadCompleteHandler(arg1:Event):void
		{
			loader.removeEventListener(Event.COMPLETE, this.loadCompleteHandler);
			addChild(loader);
			var loc1:* = loader.content;
			loc1.userData = this.userData;
			loc1.loadBar = this.loadBar;
			loc1.loadTxt = this.loadTxt;
			loc1.barBack = this.barBack;
			//GameLoadBar.instance.setProgress(PreloaderConfig.LOGIN_GAME, 0.8, 1);
		}

		private function loadProgressHandler(arg1:ProgressEvent):void
		{
			//this._text.text="正在加载..." + Math.round(100 * arg1.bytesLoaded / arg1.bytesTotal) + "%";
		}

		private function loadErrorHandler(arg1:ErrorEvent):void
		{
			this.loadTxt.text="资源加载失败！" + (arg1.target as LoaderInfo).url;
		}

		private function onSocketData(bytes:ByteArray):void
		{
			var opCode:int;
			var data:Object;
			var fun:Function;

			opCode=bytes.readShort();
			data=bytes.readObject();

			if (callback != null)
			{
				callback.call(null, data);
			}
		}

		/**
		 * 为避免一次接收到多条数据包，必须进行数据包的分离解码
		 * 网络数据解码
		 */
		private function receivedHandler(event:ProgressEvent):void
		{
			//开始读取数据的标记
			//每读取一条数据bytesAvailable值将随之减少
			//while (socket.bytesAvailable>=headLen) {
			while (sc.bytesAvailable)
			{
				if (!readFlag && sc.bytesAvailable >= headLen)
				{
					//读取数据长度
					dataLength=sc.readShort();
					readFlag=true;
				}
				//如果为0,表示收到异常消息，避免无限循环地等待
				if (dataLength == 0)
				{
					//dispatchEvent(new NetEvent(NetEvent.NULL_STREAM));
					return;
				}
				//数据流里的数据满足条件，开始读数据
				if (readFlag)
				{
					if (sc.bytesAvailable < dataLength)
					{
						dataLength=dataLength - sc.bytesAvailable;
						sc.readBytes(byteBuffer, byteBuffer.length, sc.bytesAvailable);
					}
					else
					{
						sc.readBytes(byteBuffer, byteBuffer.length, dataLength);
						byteBuffer.position=0;
						onSocketData(byteBuffer);

						byteBuffer.clear();
						dataLength=0;
						readFlag=false;
					}
				}
			}
		}

		public function send(code:int, data:Object, callbackHandler:Function=null):void
		{

			if (sc.connected)
			{
				if (callbackHandler != null)
					this.callback=callbackHandler;
				var bytes:ByteArray=new ByteArray();
				bytes.writeShort(code);
				bytes.writeObject(data);

				sc.writeShort(bytes.length);
				sc.writeBytes(bytes);

				sc.flush();
			}
		}
	}
}